//
//  STEternalScrollView.swift
//  STEternalScrollView
//
//  Created by Toj on 7/26/22.
//

import UIKit

private let viewCount = 3

protocol STEternalScrollViewDelegate: NSObjectProtocol {
    func eternalScrollView(_ view: STEternalScrollView, didTapSelected index: Int)
}

extension STEternalScrollView: STEternalScrollViewDelegate {
    func eternalScrollView(_ view: STEternalScrollView, didTapSelected index: Int) { }
}

typealias STEternalScrollable = UIView & STEternalProtocol
class STEternalScrollView: UIView {
    
    public weak var delegate: STEternalScrollViewDelegate?
    
    public var datasource: [STEternalModel]? {
        didSet {
            let count = datasource?.count ?? 0
            // 设置页码
            setPageControl(count)
            
            layoutIfNeeded()
            
            // 设置内容
            updateContent()
            
            if count <= 1 {
                scrollView.isScrollEnabled = false
                return
            }
            
            // 开始定时器
            startTimer()
        }
    }

    public var timeInterval: TimeInterval = 3
    public var isScrollDirectionPortrait = false
    
    
    private var contentViews: [STEternalScrollable] = []
    // STEternalScrollable = UIView + STEternalProtocol
    // STEternalScrollable = 视图 + 赋值协议
    public func register(viewClass: STEternalScrollable.Type)  {
        contentViews.removeAll()
        setupRegisterViews(viewClass: viewClass)
    }
    
    private lazy var scrollView: UIScrollView = {
        let view = UIScrollView()
        view.showsHorizontalScrollIndicator = false
        view.showsVerticalScrollIndicator = false
        view.isPagingEnabled = true
        view.bounces = false
        view.delegate = self
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(didTapItem))
        view.addGestureRecognizer(tap)
        
        return view
    }()
    
    private(set) lazy var pageControl: STPageControl = {
        let view = STPageControl()
        return view
    }()
    
    private var timer: Timer?
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupMakeUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        setupLayoutSubViews()
    }
    
    private func setPageControl(_ itemCount: Int){
        
        pageControl.numberOfPages = itemCount
        pageControl.currentPage = 0
        pageControl.isHidden = itemCount <= 1
    }
    
    @objc private func didTapItem() {
        delegate?.eternalScrollView(self, didTapSelected: pageControl.currentPage)
    }
    
    // 内容更新
    private func updateContent() {
        
        // 设置图片
        for i in 0..<viewCount {
            let view = contentViews[i]
            var index = pageControl.currentPage
            
            if i == 0 {
                index -= 1
            }
            else if i == 2 {
                index += 1
            }
            
            if index < 0 {
                index = pageControl.numberOfPages - 1
            }
            else if index >= pageControl.numberOfPages {
                index = 0
            }
            view.tag = index
            let model = datasource?[index]
            view.model = model
        }
        
        // 设置偏移量在中间
        if (self.isScrollDirectionPortrait) {
            scrollView.contentOffset = CGPoint(x: 0, y: scrollView.frame.size.height)
            return
        }
        
        scrollView.contentOffset = CGPoint(x: scrollView.frame.size.width, y: 0)
    }
    
    // 定时器处理
    private func startTimer() {
        if timer != nil { return }
        
        let timer_ = Timer.st_scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(nextCell), userInfo: nil, repeats: true)
        timer = timer_
    }
    
    @objc private func nextCell() {
        if isScrollDirectionPortrait {
            let contentOffset = CGPoint(x: 0, y: 2 * scrollView.frame.size.height)
            scrollView.setContentOffset(contentOffset, animated: true)
            return
        }
        
        let contentOffset = CGPoint(x: 2 * scrollView.frame.size.width, y: 0)
        scrollView.setContentOffset(contentOffset, animated: true)
    }
    
    private func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
}

extension STEternalScrollView: UIScrollViewDelegate {
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // 找出最中间的那个图片控件
        var page = 0
        
        var minDistance: CGFloat = CGFloat.greatestFiniteMagnitude
        
        for i in 0..<viewCount {
            let view = contentViews[i]
            var distance = CGFloat.zero
            
            if isScrollDirectionPortrait {
                distance = abs(view.frame.origin.y - scrollView.contentOffset.y)
            }
            else {
                distance = abs(view.frame.origin.x - scrollView.contentOffset.x)
            }
            if (distance < minDistance) {
                minDistance = distance
                page = view.tag
            }
        }
        if pageControl.currentPage == page { return }
        pageControl.currentPage = page
    }
    
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        startTimer()
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        stopTimer()
    }
    
   
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        updateContent()
    }
    
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        updateContent()
    }
}

extension STEternalScrollView {
    
    private func setupRegisterViews(viewClass: STEternalScrollable.Type) {
        // 图片控件
        for _ in 0..<viewCount {
            let view = viewClass.init()
            scrollView.addSubview(view)
            contentViews.append(view)
        }
    }
    
    private func setupMakeUI() {
        addSubview(scrollView)
        
        addSubview(pageControl)
        
        setupRegisterViews(viewClass: UIImageView.self)
    }
    
    private func relayoutSubView() {
        let swidth = scrollView.frame.width
        let sheight = scrollView.frame.height
        if swidth == 0 || sheight == 0 { return }
        
        
        let size = pageControl.sizeForNumberOfPages
        
        let x = swidth - size.width - 8
        let y = sheight - size.height - 8
        
        pageControl.frame = CGRect(x: x, y: y, width: size.width, height: size.height)
    }
    
    private func setupLayoutSubViews() {
        let selfWidth = bounds.width
        let selfHeight = bounds.height
        
        scrollView.frame = bounds
        let swidth = scrollView.frame.width
        let sheight = scrollView.frame.height
        
        var contentWidth = CGFloat.zero
        var contentHeight = CGFloat.zero
        if isScrollDirectionPortrait {
            contentHeight = CGFloat(viewCount) * selfHeight
        }
        else {
            contentWidth = CGFloat(viewCount) * selfWidth
        }
        scrollView.contentSize = CGSize(width: contentWidth, height: contentHeight)
            
        var cx = CGFloat.zero
        var cy = CGFloat.zero
        var cwidth = CGFloat.zero
        var cheight = CGFloat.zero
        for i in 0..<viewCount {
            let view = contentViews[i]
            
            if isScrollDirectionPortrait {
                cx = 0
                cy = i.to_double * sheight
                cwidth = swidth
                cheight = sheight
            }
            else {
                cx = i.to_double * swidth
                cy = 0
                cwidth = swidth
                cheight = sheight
            }
            
            let cframe = CGRect(x: cx, y: cy, width: cwidth, height: cheight)
            view.frame = cframe
        }
        
        relayoutSubView()
    }
}
